<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  
  
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <title>
    Yaf---写在前面 |
    
    无敌小笼包</title>
  
    <link rel="shortcut icon" href="/favicon.png">
  
  <link rel="stylesheet" href="/css/style.css">
  
    <link rel="stylesheet" href="/fancybox/jquery.fancybox.min.css">
  
  <script src="/js/pace.min.js"></script>
</head>

<body>
<main class="content">
  <section class="outer">
  <article id="post-yaf01" class="article article-type-post" itemscope itemprop="blogPost">

  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      Yaf---写在前面
    </h1>
  

      </header>
    

    
      <div class="article-meta">
        <a href="/2016/07/28/yaf01/" class="article-date">
  <time datetime="2016-07-28T15:22:37.000Z" itemprop="datePublished">2016-07-28</time>
</a>
        
  <div class="article-category">
    <a class="article-category-link" href="/categories/Frame/">Frame</a>
  </div>

      </div>
    

    <div class="article-entry" itemprop="articleBody">
      
      
      
        <p>Yaf有着和Zend Framework相似的API, 相似的理念, 而同时又保持着对Bingo的兼容, 以此来提高开发效率, 规范开发习惯. 本着对性能的追求, Yaf把框架中不易变的部分抽象出来,采用PHP扩展实现(c语言),以此来保证性能.在作者自己做的简单测试中, Yaf和原生的PHP在同样功能下, 性能损失小于10%, 而和ZendFramework的对比中, Yaf的性能是Zend Framework的50-60倍.<br><a id="more"></a></p>
<blockquote>
<p>天下武功无坚不破，唯快不破</p>
</blockquote>
<ol>
<li>用C语言开发的PHP框架, 相比原生的PHP, 几乎不会带来额外的性能开销.</li>
<li>所有的框架类, 不需要编译, 在PHP启动的时候加载, 并常驻内存.</li>
<li>更短的内存周转周期, 提高内存利用率, 降低内存占用率.</li>
<li>灵巧的自动加载. 支持全局和局部两种加载规则, 方便类库共享.</li>
<li>高性能的视图引擎.</li>
<li>高度灵活可扩展的框架, 支持自定义视图引擎, 支持插件, 支持自定义路由等等.</li>
<li>内建多种路由, 可以兼容目前常见的各种路由协议.</li>
<li>强大而又高度灵活的配置文件支持. 并支持缓存配置文件, 避免复杂的配置结构带来的性能损失.</li>
<li>在框架本身,对危险的操作习惯做了禁止.</li>
<li>更快的执行速度, 更少的内存占用</li>
</ol>
<h3 id="Yaf的安装-Windows"><a href="#Yaf的安装-Windows" class="headerlink" title="Yaf的安装 Windows"></a>Yaf的安装 Windows</h3><p>Yaf只支持PHP5.2及以上的版本<br>Yaf需要SPL的支持. SPL在PHP5中是默认启用的扩展模块<br>Yaf需要PCRE的支持. PCRE在PHP5中是默认启用的扩展模块<br>在 Windows 系统下安装<br>PHP 5.2+</p>
<ol>
<li>打开yaf在php官网上的目录：<a href="http://pecl.php.net/package/yaf" target="_blank" rel="noopener">http://pecl.php.net/package/yaf</a></li>
<li>目前yaf的最新版为3.0.0,仅支付php7,建议选择2.3.5版本</li>
<li>我这里选择2.3.5后面的win图标+DLL字样的链接，进入页面下载php_yaf.dll</li>
<li>在打开的页面根据自己的环境来选择对应的版本，我这里选择的是php5.6 Thread Safe (TS)x86(php5.6版本 安全线程 32位操作系统)</li>
<li>点击后自动下载了一个压缩包：php_yaf-2.3.5-5.6-ts-vc11-x86.zip</li>
<li>把压缩包中的php_yaf.dll复制出来，打到你的php目录，打开目录下的ext文件夹，粘贴进去</li>
<li>再打开您的PHP配置文件php.ini，加入 ‘extension=php_yaf.dll’,重启web服务器,就OK了</li>
</ol>
<p><img src="/blog-img/yaf2.bmp" alt="" title="phpini路径"><br><img src="/blog-img/yaf.jpg" alt="" title="phpinfo显示成功螃蟹图标再现"></p>
<hr>
<h3 id="Yaf的安装-Linux"><a href="#Yaf的安装-Linux" class="headerlink" title="Yaf的安装 Linux"></a>Yaf的安装 Linux</h3><p>下载Yaf的最新版本, 解压缩以后, 进入Yaf的源码目录, 依次执行(其中PHP_BIN是PHP的bin目录):</p>
<blockquote>
<p><code>cd /usr/local/src</code>#进入软件包存放目录<br><code>tar zxvf yaf-2.3.5.tgz</code>#解压<br><code>cd yaf-2.3.5</code>#进入安装目录<br><code>/usr/local/php/bin/phpize</code>#用phpize生成configure配置文件<br><code>./configure --with-php-config=/usr/local/php/bin/php-config</code> #配置<br><code>make</code><br><code>make install</code><br>安装完成之后，出现下面的安装路径<br><code>/usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/</code><br>配置php支持<br><code>vim /usr/local/php/etc/php.ini</code> #编辑配置文件，在最后一行添加以下内容<br><code>extension=&quot;yaf.so&quot;</code><br><code>:wq!</code> #保存退出<br> 重启服务<br><code>sudo service nginx restart</code><br><code>sudo /etc/init.d/php-fpm restart</code><br>查看<br><code>php -m</code> 看到神秘的yaf 就说明安装成功了</p>
</blockquote>
<p><img src="/blog-img/yaf3.bmp" alt=""><br><img src="/blog-img/yaf4.bmp" alt=""></p>
<p><code>Yaf_Request_Abstract</code>的<code>getPost</code>, <code>getQuery</code>等方法, 并没有对应的<code>setter</code>方法. 并且这些方法是直接从PHP内部的$_POST, $_GET等大变量的原身变量只读的查询值, 所以就有一个问题:通过在PHP脚本中对这些变量的修改, 并不能反映到 <code>getPost/getQuery</code> 等方法上</p>
<h3 id="yaf-的常量"><a href="#yaf-的常量" class="headerlink" title="yaf 的常量"></a>yaf 的常量</h3><table>
<thead>
<tr>
<th>常量(启用命名空间后的常量名)</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>YAF_VERSION(Yaf\VERSION)</td>
<td>Yaf框架的三位版本信息</td>
</tr>
<tr>
<td>YAF_ENVIRON(Yaf\ENVIRON)</td>
<td>Yaf的环境常量, 指明了要读取的配置的节, 默认的是product</td>
</tr>
<tr>
<td>YAF_ERR_DISPATCH_FAILED(Yaf\ERR\DISPATCH_FAILED)</td>
<td>Yaf的错误代码常量, 表示分发失败, 值为514</td>
</tr>
<tr>
<td>YAF_ERR_NOTFOUND_MODULE(Yaf\ERR\NOTFOUD\MODULE)</td>
<td>Yaf的错误代码常量, 表示找不到指定的模块, 值为515</td>
</tr>
<tr>
<td>YAF_ERR_NOTFOUND_CONTROLLER(Yaf\ERR\NOTFOUD\CONTROLLER)</td>
<td>Yaf的错误代码常量, 表示找不到指定的Controller, 值为516</td>
</tr>
<tr>
<td>YAF_ERR_NOTFOUND_ACTION(Yaf\ERR\NOTFOUD\ACTION)</td>
<td>Yaf的错误代码常量, 表示找不到指定的Action, 值为517</td>
</tr>
<tr>
<td>YAF_ERR_NOTFOUND_VIEW(Yaf\ERR\NOTFOUD\VIEW)</td>
<td>Yaf的错误代码常量, 表示找不到指定的视图文件, 值为518</td>
</tr>
<tr>
<td>YAF_ERR_CALL_FAILED(Yaf\ERR\CALL_FAILED)</td>
<td>Yaf的错误代码常量, 表示调用失败, 值为519</td>
</tr>
<tr>
<td>YAF_ERR_AUTOLOAD_FAILED(Yaf\ERR\AUTOLOAD_FAILED)</td>
<td>Yaf的错误代码常量, 表示自动加载类失败, 值为520</td>
</tr>
<tr>
<td>YAF_ERR_TYPE_ERROR(Yaf\ERR\TYPE_ERROR)</td>
<td>Yaf的错误代码常量, 表示关键逻辑的参数错误, 值为521</td>
</tr>
</tbody>
</table>
<h3 id="yaf-的配置项"><a href="#yaf-的配置项" class="headerlink" title="yaf 的配置项"></a>yaf 的配置项</h3><table>
<thead>
<tr>
<th>选项名称</th>
<th>默认值</th>
<th>可修改范围</th>
<th>更新记录</th>
</tr>
</thead>
<tbody>
<tr>
<td>yaf.environ</td>
<td>product</td>
<td>PHP_INI_ALL</td>
<td>环境名称, 当用INI作为Yaf的配置文件时, 这个指明了Yaf将要在INI配置中读取的节的名字</td>
</tr>
<tr>
<td>yaf.library</td>
<td>NULL</td>
<td>PHP_INI_ALL</td>
<td>全局类库的目录路径</td>
</tr>
<tr>
<td>yaf.cache_config</td>
<td>0</td>
<td>PHP_INI_SYSTEM</td>
<td>是否缓存配置文件(只针对INI配置文件生效), 打开此选项可在复杂配置的情况下提高性能</td>
</tr>
<tr>
<td>yaf.name_suffix</td>
<td>1</td>
<td>PHP_INI_ALL</td>
<td>在处理Controller, Action, Plugin, Model的时候, 类名中关键信息是否是后缀式, 比如UserModel, 而在前缀模式下则是ModelUser</td>
</tr>
<tr>
<td>yaf.name_separator</td>
<td>“”</td>
<td>PHP_INI_ALL</td>
<td>在处理Controller, Action, Plugin, Model的时候, 前缀和名字之间的分隔符, 默认为空, 也就是UserPlugin, 加入设置为”_”, 则判断的依据就会变成:”User_Plugin”, 这个主要是为了兼容ST已有的命名规范</td>
</tr>
<tr>
<td>yaf.forward_limit</td>
<td>5</td>
<td>PHP_INI_ALL</td>
<td>forward最大嵌套深度</td>
</tr>
<tr>
<td>yaf.use_namespace</td>
<td>0</td>
<td>PHP_INI_SYSTEM</td>
<td>开启的情况下, Yaf将会使用命名空间方式注册自己的类, 比如Yaf_Application将会变成Yaf\Application</td>
</tr>
<tr>
<td>yaf.use_spl_autoload</td>
<td>0</td>
<td>PHP_INI_ALL</td>
<td>开启的情况下, Yaf在加载不成功的情况下, 会继续让PHP的自动加载函数加载, 从性能考虑, 除非特殊情况, 否则保持这个选项关闭</td>
</tr>
</tbody>
</table>
<blockquote>
<p>在开启yaf.cache_config的情况下, Yaf会使用INI文件路径作为Key, 这就有一个陷阱, 就是如果在一台服务器上同时运行俩个应用, 那么它们必须不能使用同一个路径名下的INI配置文件, 否则就会出现Application Path混乱的问题. 所以, 尽量不要使用相对路径.</p>
</blockquote>
<h3 id="快速开始"><a href="#快速开始" class="headerlink" title="快速开始"></a>快速开始</h3><pre><code>├──public
│    ├── index.php  入口文件
│    ├── .htaccess  重写规则 
│    ├── css
│    ├── img
│    ├── js
├──conf
│    ├── application.ini 配置文件  
├──application
│    ├── Controllers
│            ├── Index.php 默认控制器 
│    ├── views 
│            ├── Index 控制器名
│                  ├── index.phtml 默认视图
├──modules 其他模块
├──library 本地类库
├──models  model目录
├──plugins 插件目录
</code></pre><h3 id="入口文件"><a href="#入口文件" class="headerlink" title="入口文件"></a>入口文件</h3><p>入口文件是所有请求的入口, 一般都借助于rewrite规则, 把所有的请求都重定向到这个入口文件.</p>
<p>一个经典的入口文件public/index.php</p>
<pre><code>&lt;?php
define(&quot;APP_PATH&quot;,  realpath(dirname(__FILE__) . &apos;/../&apos;)); /* 指向public的上一级 */
$app  = new Yaf_Application(APP_PATH . &quot;/conf/application.ini&quot;);
$app-&gt;run();   
</code></pre><h3 id="重写规则"><a href="#重写规则" class="headerlink" title="重写规则"></a>重写规则</h3><p>除非我们使用基于query string的路由协议(Yaf_Route_Simple, Yaf_Route_Supervar), 否则我们就需要使用WebServer提供的Rewrite规则, 把所有这个应用的请求, 都定向到上面提到的入口文件.</p>
<p>Apache的Rewrite (httpd.conf)</p>
<pre><code>#.htaccess, 当然也可以写在httpd.conf
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php
</code></pre><p>Nginx的Rewrite (nginx.conf)</p>
<pre><code>server {
  listen ****;
  server_name  domain.com;
  root   document_root;
  index  index.php index.html index.htm;

  if (!-e $request_filename) {
    rewrite ^/(.*)  /index.php/$1 last;
  }
</code></pre><p>}</p>
<p>Lighttpd的Rewrite (lighttpd.conf)</p>
<pre><code>$HTTP[&quot;host&quot;] =~ &quot;(www.)?domain.com$&quot; {
  url.rewrite = (
     &quot;^/(.+)/?$&quot;  =&gt; &quot;/index.php/$1&quot;,
  )
}
</code></pre><p>SAE的Rewrite (config.yaml)</p>
<pre><code>name: your_app_name
version: 1
handle:
    - rewrite: if(!is_dir() &amp;&amp; !is_file() &amp;&amp; path ~ &quot;^(.*)$&quot; ) goto &quot;/index.php&quot;
</code></pre><blockquote>
<p>[注意]    注意每种Server要启用Rewrite都需要特别设置, 如果对此有疑问.. RTFM<br>配置文件</p>
</blockquote>
<p>在Yaf中, 配置文件支持继承, 支持分节. 并对PHP的常量进行支持. 你不用担心配置文件太大造成解析性能问题, 因为Yaf会在第一个运行的时候载入配置文件, 把格式化后的内容保持在内存中. 直到配置文件有了修改, 才会再次载入.</p>
<p>一个简单的配置文件application/conf/application.ini</p>
<pre><code>[product]
;支持直接写PHP中的已定义常量
application.directory=APP_PATH &quot;/application/&quot; 
</code></pre><blockquote>
<p>控制器</p>
</blockquote>
<p>在Yaf中, 默认的模块/控制器/动作, 都是以Index命名的, 当然,这是可通过配置文件修改的.<br>对于默认模块, 控制器的目录是在application目录下的controllers目录下, Action的命名规则是”名字+Action”</p>
<p> 默认控制器application/controllers/Index.php</p>
<pre><code>&lt;?php
class IndexController extends Yaf_Controller_Abstract {
   public function indexAction() {//默认Action
       $this-&gt;getView()-&gt;assign(&quot;content&quot;, &quot;Hello World&quot;);
   }
}
?&gt;
</code></pre><blockquote>
<p>视图文件</p>
</blockquote>
<p>Yaf支持简单的视图引擎, 并且支持用户自定义自己的视图引擎, 比如Smarty.对于默认模块, 视图文件的路径是在application目录下的views目录中以小写的action名的目录中.</p>
<p>一个默认Action的视图application/views/index/index.phtml</p>
<pre><code>&lt;html&gt;
 &lt;head&gt;
   &lt;title&gt;Hello World&lt;/title&gt;
 &lt;/head&gt;
 &lt;body&gt;
  &lt;?php echo $content;?&gt;
 &lt;/body&gt;
&lt;/html&gt;
</code></pre><blockquote>
<p>运行在浏览器输入</p>
</blockquote>
<p><a href="http://www.yourhostname.com/application/index.php" target="_blank" rel="noopener">http://www.yourhostname.com/application/index.php</a></p>
<p>看到了Hello World输出吧?</p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://blog.mango16.cc/2016/07/28/yaf01/" data-id="cjrbtw1zr002r6d8htag5lh4t"
         class="article-share-link">分享</a>
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Yaf/">Yaf</a></li></ul>

    </footer>

  </div>

  
    
  <nav class="article-nav">
    
      <a href="/2016/07/29/yaf02/" class="article-nav-link">
        <strong class="article-nav-caption">前一篇</strong>
        <div class="article-nav-title">
          
            Yaf---加载规则插件使用
          
        </div>
      </a>
    
    
      <a href="/2016/07/07/HTTPcode/" class="article-nav-link">
        <strong class="article-nav-caption">后一篇</strong>
        <div class="article-nav-title">HTTP常见状态码</div>
      </a>
    
  </nav>


  

  
    
  <div class="gitalk" id="gitalk-container"></div>
  <link rel="stylesheet" href="https://unpkg.com/gitalk/dist/gitalk.css">
  <script src="https://unpkg.com/gitalk/dist/gitalk.min.js"></script>
  <script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
  <script type="text/javascript">
      var gitalk = new Gitalk({
        clientID: 'caba8826a61790936307',
        clientSecret: '09a15037dcab30d9adf35a53ec6961939169f797',
        repo: 'm9rco.github.io',
        owner: 'm9rco',
        admin: ['m9rco'],
        // id: location.pathname,      // Ensure uniqueness and length less than 50
        id: md5(location.pathname),
        distractionFreeMode: false  // Facebook-like distraction free mode
      })

  gitalk.render('gitalk-container')
  </script>

  

</article>



</section>
  <footer class="footer">
  
  <div class="outer">
    <ul class="list-inline">
      <li>&copy; 2019 无敌小笼包</li>
      <i class="pulse"></i>
    </ul>
  </div>
</footer>

</main>
<aside class="sidebar">
  <button class="navbar-toggle"></button>

<nav class="navbar">
  
    <div class="logo">
      <a href="/"><img src="/images/hexo.svg" alt="无敌小笼包"></a>
    </div>
  
  <ul class="nav nav-main">
    
      <li class="nav-item">
        <a class="nav-item-link" href="/">主页</a>
      </li>
    
      <li class="nav-item">
        <a class="nav-item-link" href="/archives">归档</a>
      </li>
    
      <li class="nav-item">
        <a class="nav-item-link" href="/gallery">相册</a>
      </li>
    
      <li class="nav-item">
        <a class="nav-item-link" href="/nagging">叽咕</a>
      </li>
    
      <li class="nav-item">
        <a class="nav-item-link" href="/about">关于</a>
      </li>
    
    <li class="nav-item">
      <a class="nav-item-link nav-item-search" title="Search">
        <i class="fe fe-search"></i>
        搜索
      </a>
    </li>
  </ul>
</nav>

<nav class="navbar navbar-bottom">
  <ul class="nav">
    <li class="nav-item">
      
        <a class="nav-item-link" target="_blank" href="/atom.xml" title="RSS Feed">
          <i class="fe fe-feed"></i>
        </a>
      
    </li>
  </ul>
</nav>

<div class="search-form-wrap">
  <div class="local-search local-search-plugin">
  <input type="search" id="local-search-input" class="local-search-input" placeholder="Search...">
  <div id="local-search-result" class="local-search-result"></div>
</div>
</div>
</aside>
  <script src="/js/jquery-2.0.3.min.js"></script>
<script src="/js/lazyload.min.js"></script>


  <script src="/fancybox/jquery.fancybox.min.js"></script>



  <script src="/js/search.js"></script>


<script src="/js/ocean.js"></script>

</body>
</html>